/* (C) C.D.F. Miller, Heriot-Watt University, March 1984
 *
 *	Permission is hereby given to reproduce or modify this
 *	software freely, provided that this notice be retained,
 *	and that no use be made of the software for commercial
 *	purposes without the express written permission of the
 *	author.
 */

/* lbl.c:
 *	main program - decode switches and arguments
 *	and process each input file.
 * usage:
 *	lbl [ -d<char> ] [ -m<macro> ] [ -l ] [ -s ]
 *		-d	<char> delimits in-line occurrences of a tag
 *		-m	<macro> defines a tag value
 *		-l	list label definitions
 *		-s	suppress nroff output (implies -l)
 * defaults:
 *	-d@ -mL=
 */

#include        <string.h>
#include        <unistd.h>
#include        <stdlib.h>
#include        <err.h>
#include        <sysexits.h>
#include        <limits.h>
#include        <assert.h>
#include        "lbl.h"
#include        "signals.h"
#include        "scan.h"
#include        "rescan.h"
#include	"list.h"
#include	"externs.h"

int	decode(int argc, char *argv[]);

/** Size of macroname[] */
static const int MACRONAME_MAX = 3;

int
main(int argc, char *argv[])
{
	int nflags;
	int anydone = 0;
	static char standard[] = "standard input";

	if (argc != 0) {
		argc--;
		progname = *(argv++);
	}
	nflags = decode(argc, argv);
	argc -= nflags;
	argv += nflags;

	/*
	 * Remaining arguments must be filenames; treat "-" specially as
	 * standard input. If no arguments, use atandard input.
	 */

	/*
	 * Pass 1: copy to temp file, building table of tags
	 */
	if (!sflag) {
		mktemp(tempname);
		if ((tempfile = fopen(tempname, "w")) == NULL)
			errx(EX_CANTCREAT, "%scannot make temporary file",
			     maybe_loc());
		setsignals();
	}
	if (argc == 0) {
		scan(standard, stdin);
		anydone = 1;
	}
	else {
		while (argc != 0) {
			if (strcmp(argv[0], "-") == 0) {
				anydone = 1;
				scan(standard, stdin);
			}
			else {
				FILE *input;

				if ((input = fopen(argv[0], "r")) == NULL)
					warnx("%scannot open %s", maybe_loc(),
					      argv[0]);
				else {
					anydone = 1;
					scan(argv[0], input);
					fclose(input);
				}
			}
			argc--;
			argv++;
		}
	}
	if (!sflag)
		fclose(tempfile);
	if (lflag)
		listdefs();

	/*
	 * Pass 2: translate tags
	 */

	if (!anydone) {
		unlink(tempname);
		exit(3);
	}
	if (!sflag) {
		if ((tempfile = fopen(tempname, "r")) == NULL)
			errx(EX_NOINPUT,
			     "%stemporary file vanished before rescan!",
			     maybe_loc());
		rescan();
		unlink(tempname);
	}
	exit(0);
}

/* Decode argument list */
int
decode(int argc, char *argv[])
{
	int ch;
	int nflags = 0;

	while ((ch = getopt(argc, argv, ":d:m:ls")) != -1) {
		switch (ch) {
		case 'd':
			if (strlen(optarg) != 1)
				errx(EX_USAGE,
				     "%sdelimiter must be 1 character",
				     maybe_loc());
			delimiter = optarg[0];
			break;
		case 'm':
			if (strlen(optarg) != 2)
				errx(EX_USAGE,
				     "%smacro name must be 2 characters",
				     maybe_loc());
			strlcpy(macroname, optarg, MACRONAME_MAX);
			break;
		case 'l':
			lflag = 1;
			break;
		case 's':
			lflag = sflag = 1;
			break;
		case ':':
			assert(optopt == 'd' || optopt == 'm');
			switch (optopt) {
			case 'd':
				errx(EX_USAGE, "%smissing delimiter after -d",
				     maybe_loc());
			/*
			 * NOTREACHED
			 */
			case 'm':
				errx(EX_USAGE,
				     "%smacro name must be 2 characters",
				     maybe_loc());
				/*
				 * NOTREACHED
				 */
			}
			break;
		case '?':
		default:
			errx(EX_USAGE, "%sunknown flag '%c'", maybe_loc(),
			     optopt);
			/*
			 * NOTREACHED
			 */
		}
		nflags++;
	}
	return nflags;
}

char   *
maybe_loc(void)
{
	static char result[LINE_MAX];

	if (filename != NULL)
		snprintf(result, LINE_MAX, "%s, line %ld - ", filename,
		         fileline);
	else
		result[0] = '\x00';
	return result;
}
